%% input
% hk PJmax phiw kexi

Nt = 128;


% 设置用户数量
K = 10;
% K = 3; 
Nrc = 2;
Nrj = 1;
Lk = 3;
Lw = 3;

lambda_LOSNLOS = zeros(Lk,1) + 1j * zeros(Lk,1);
for i = 1:Lk 
    if(i == 1)
        lambda_LOSNLOS(i) = randn()+ 1j * randn();
    else
        lambda_LOSNLOS(i) = 0.01 * ( randn() + 1j * randn() );
    end
end

kesi = 0.01;
Pcmax = 10;


% 生成随机的用户位置，假设用户在半径为R的圆内随机分布
R = 100; % 半径
user_positions = R * rand(K, 2); % 生成K个用户的随机二维坐标

% 生成Willie
willie_position = [50, 50];
willie_angle = atan2(willie_position(1),willie_position(2));

% 计算每个用户以及窃听者的发送角度（相对于原点）
send_angles = atan2(user_positions(:, 2), user_positions(:, 1));

hk_vectors = zeros(Nt,K);
sigma_k = zeros(K,1);


% SV channle  (32)
for i = 1:K
    sigma_k(i) = db2pow(-30);
    for j = 1:Lk
         hk_vectors(:,i) = hk_vectors(:,i) + sqrt(Nt/Lk) * ( lambda_LOSNLOS(j) * ULA_fun(send_angles(i), Nt) ...
             );
    end
end

Hc = hk_vectors.';

% (35)
Wj = eye(Nt) - Hc' * inv(Hc*Hc') * Hc;

% (37)
wjopt = Wj * Wj' * conj( ULA_fun(willie_angle, Nt) ) / norm( Wj * Wj' * conj( ULA_fun(willie_angle, Nt) ) );


Wc = eye(Nt) - conj(ULA_fun(willie_angle, Nt) ) * inv( ULA_fun(willie_angle, Nt).' ...
    *  conj(ULA_fun(willie_angle, Nt) )  ) ...
    * ULA_fun(willie_angle, Nt).';

[Woc, R] = qr(Wc);



% (42)  因为是发送到K个用户，所以要加入对K个用户的循环
for k = 1:K
    hok = Woc.' * hk_vectors(:,k);
    Qk = conj(hok) * hok.' / sigma_k(k);
    episionlower = zeros(Nt - 1, 1)
    objBefore =10;
    objAfter = 10 * objBefore;
    count = 0;
    objAfterSet = [];
    while(abs((objAfter-objBefore)/objBefore)>= 5e-4 && count~=50)
      fprintf('第%g个用户，第%g次内部迭代\n', k , count);
      objBefore = objAfter;
      %%%%%%% CVX 使用框架 
      cvx_begin quiet
        variable t 
        variable epision(Nt - 1, 1) 
        maximize t
        subject to
            2 * real( episionlower' * Qk * epision ) - episionlower'*Qk*episionlower>= t;
            norm(epision) <= 1;
      cvx_end
      %%%%%
      if(cvx_status(1)=='S')
           % 更新epision，实现迭代的下界最大化
           episionlower = epision;
           objAfter = epision' * Qk * epision;
      end
      count = count + 1;
      objAfterSet=[objAfterSet, objAfter];
    end
end



